
package net.atremmedia.gwt.actionjava.examples.advanced.samples.nodes;

import actionjava.display.Graphics;
import actionjava.display.Sprite;
import actionjava.geom.Color;

public class NodesMass extends Sprite
{
	public static final double STAGE_WIDTH = 800;
	public static final double STAGE_HEIGHT = 600;
	public static final int NUM_PARTICLES = 125;

	private double minDist = 100;
	private double springAmount = .001;
	private Particle[] particles;
	private Graphics graphics;

	public void start()
	{
		// disableMeasurement();
		graphics = getGraphics();

		Particle particle;
		particles = new Particle[NUM_PARTICLES];
		for(int i = 0;i < NUM_PARTICLES;i++) {
			double size = Math.random() * 10 + 2;
			particle = new Particle(size, 0xFFFFFF);
			particle.setX(Math.random() * STAGE_WIDTH);
			particle.setY(Math.random() * STAGE_HEIGHT);
			particle.setVx(Math.random() * 6 - 3);
			particle.setVy(Math.random() * 6 - 3);
			particle.setMass(size);
			addChild(particle);
			particles[i] = particle;
		}
	}

	public void update()
	{
		graphics.clear();
		Particle particle;
		for(int i = 0;i < NUM_PARTICLES;i++) {
			particle = particles[i];
			particle.setX(particle.getX() + particle.getVx());
			particle.setY(particle.getY() + particle.getVy());

			if(particle.getX() > STAGE_WIDTH) {
				particle.setX(0);
			} else if(particle.getX() < 0) {
				particle.setX(STAGE_WIDTH);
			}
			if(particle.getY() > STAGE_HEIGHT) {
				particle.setY(0);
			} else if(particle.getY() < 0) {
				particle.setY(STAGE_HEIGHT);
			}
		}

		for(int i = 0;i < NUM_PARTICLES - 1;i++) {
			Particle partA = particles[i];
			for(int j = i + 1;j < NUM_PARTICLES;j++) {
				Particle partB = particles[j];
				spring(partA, partB);
			}
		}
	}

	private void spring(Particle partA, Particle partB)
	{
		double dx = partB.getX() - partA.getX();
		double dy = partB.getY() - partA.getY();
		double dist = Math.sqrt(dx * dx + dy * dy);
		if(dist < minDist) {
			graphics.beginStroke(Color.getRGBA(0xFFFFFF, (1 - dist / minDist)));
			graphics.moveTo(partA.getX(), partA.getY());
			graphics.lineTo(partB.getX(), partB.getY());
			double ax = dx * springAmount;
			double ay = dy * springAmount;

			partA.plusVx(ax / partA.getMass());
			partA.plusVy(ay / partA.getMass());
			partB.minVx(ax / partB.getMass());
			partB.minVy(ay / partB.getMass());
		}
	}
}
